package com.sunyard.utils.wxv3Util;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * @author : ziliang.zhou
 * @version : 1.0
 * @date : 2020-08-07 21:19
 * @description : httpclient 辅助类
 **/
@Slf4j
@Component
public class HttpClientHelper {

    public static final String ACCEPT_TYPE_JSON = "application/json";
    public static final String ACCEPT_TYPE_HTML = "text/html";
    public static final String ACCEPT_TYPE_XML = "application/xml";
    public static final String ACCEPT_TYPE_X_WWW = "application/x-www-form-urlencoded";
    public static final int DEFAULT_SO_TIMEOUT = 30000;
    public static final int DEFAULT_CONN_TIMEOUT = 6000;
    public static final int DEFAULT_CONN_REQ_TIMEOUT = 5000;
    private static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    private RequestConfig requestConfig;

    @PostConstruct
    public void init() {
        this.requestConfig = RequestConfig.custom().setSocketTimeout(DEFAULT_SO_TIMEOUT).setConnectTimeout(DEFAULT_CONN_TIMEOUT).setConnectionRequestTimeout(DEFAULT_CONN_REQ_TIMEOUT).build();
    }

    @PreDestroy
    public void destory() {
        if (cm != null) {
            log.info("关闭HttpClient线程池");
            cm.shutdown();
        }

    }


    public static enum POST_MEDIA_TYPE {
        JSON,
        FORM,
        JSONSTR,
        XML;

        private POST_MEDIA_TYPE() {
        }
    }


    public String post(String url, Map<String, Object> params, POST_MEDIA_TYPE mediaType) {
        String result = null;
        HttpEntity resEntity = null;
        CloseableHttpResponse response = null;
        if (null == mediaType) {
            mediaType = POST_MEDIA_TYPE.JSON;
        }

        List<NameValuePair> list = new ArrayList();
        Iterator iterator = params.entrySet().iterator();

        while (iterator.hasNext()) {
            Map.Entry<String, String> elem = (Map.Entry) iterator.next();
            list.add(new BasicNameValuePair((String) elem.getKey(), (String) elem.getValue()));
        }

        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).setConnectionManagerShared(true).build();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(this.requestConfig);
        if (list.size() > 0) {
            UrlEncodedFormEntity entity = null;
            try {
                entity = new UrlEncodedFormEntity(list, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                log.error(e.getMessage(), e);
            }
            httpPost.setEntity(entity);
        }
        if (POST_MEDIA_TYPE.JSON == mediaType) {
            httpPost.setHeader("Accept", ACCEPT_TYPE_JSON);
            httpPost.setHeader("Content-type", ACCEPT_TYPE_JSON);
        } else if (POST_MEDIA_TYPE.FORM == mediaType) {
            httpPost.setHeader("Content-Type", ACCEPT_TYPE_X_WWW);
        }
        try {
            response = httpClient.execute(httpPost);
            if (response != null) {
                resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
        } catch (IOException var10) {
            log.error(var10.getMessage(), var10);
        } finally {
            if (resEntity != null) {
                EntityUtils.consumeQuietly(resEntity);
            }

            if (response != null) {
                try {
                    response.close();
                } catch (IOException var20) {
                    log.error("关闭HttpResponse出错，错误信息：" + var20.getMessage(), var20);
                }
            }

        }
        return result;
    }


    public String post(String url, String boundary, File file, String filename, String fileSha256, Map<String, String> headers) {
        String result = null;
        HttpEntity resEntity = null;
        CloseableHttpResponse response = null;

        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).setConnectionManagerShared(true).build();
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(this.requestConfig);
        if (headers != null && headers.size() > 0) {
            for (String key : headers.keySet()) {
                httpPost.setHeader(key, headers.get(key));
            }
        }
        //创建MultipartEntityBuilder
        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
        //设置boundary
        multipartEntityBuilder.setBoundary(boundary);
        multipartEntityBuilder.setCharset(Charset.forName("UTF-8"));
        //设置meta内容
        multipartEntityBuilder.addTextBody("meta", "{\"filename\":\"" + filename + "\",\"sha256\":\"" + fileSha256 + "\"}", ContentType.APPLICATION_JSON);
        //设置图片内容
        multipartEntityBuilder.addBinaryBody("file", file, ContentType.create("image/jpg"), filename);
        //放入内容
        httpPost.setEntity(multipartEntityBuilder.build());
        try {
            response = httpClient.execute(httpPost);
            if (response != null) {
                resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
        } catch (IOException var10) {
            log.error(var10.getMessage(), var10);
        } finally {
            if (resEntity != null) {
                EntityUtils.consumeQuietly(resEntity);
            }

            if (response != null) {
                try {
                    response.close();
                } catch (IOException var20) {
                    log.error("关闭HttpResponse出错，错误信息：" + var20.getMessage(), var20);
                }
            }
        }
        return result;
    }


    public String get(String url, Map<String, Object> params, POST_MEDIA_TYPE mediaType, Map<String, String> headers) {
        String result = null;
        HttpEntity resEntity = null;
        CloseableHttpResponse response = null;
        if (null == mediaType) {
            mediaType = POST_MEDIA_TYPE.JSON;
        }

        StringBuilder paramSB = new StringBuilder();
        if (params != null) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                paramSB.append("&").append(entry.getKey()).append("=").append(entry.getValue());
            }
        }
        if (paramSB.length() > 0) {
            url = url + "?" + paramSB.substring(1);
        }

        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).setConnectionManagerShared(true).build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(this.requestConfig);

        if (POST_MEDIA_TYPE.JSON == mediaType) {
            httpGet.setHeader("Accept", ACCEPT_TYPE_JSON);
            httpGet.setHeader("Content-type", ACCEPT_TYPE_JSON);
        } else if (POST_MEDIA_TYPE.FORM == mediaType) {
            httpGet.setHeader("Content-Type", ACCEPT_TYPE_X_WWW);
        }
        if (headers != null && headers.size() > 0) {
            for (String key : headers.keySet()) {
                httpGet.setHeader(key, headers.get(key));
            }
        }
        try {
            response = httpClient.execute(httpGet);
            if (response != null) {
                resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
        } catch (IOException var10) {
            log.error(var10.getMessage(), var10);
        } finally {
            if (resEntity != null) {
                EntityUtils.consumeQuietly(resEntity);
            }

            if (response != null) {
                try {
                    response.close();
                } catch (IOException var20) {
                    log.error("关闭HttpResponse出错，错误信息：" + var20.getMessage(), var20);
                }
            }

            return result;
        }

    }
}